package com.hangsu.train.components.service.impl;

import com.hangsu.train.common.utils.Digests;
import com.hangsu.train.components.constants.JwtConstant;
import com.hangsu.train.components.dao.RoleDao;
import com.hangsu.train.components.dao.UserDao;
import com.hangsu.train.components.entity.Role;
import com.hangsu.train.components.entity.User;
import com.hangsu.train.components.params.LoginParam;
import com.hangsu.train.components.params.PageRequestParam;
import com.hangsu.train.components.service.UserService;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import jakarta.annotation.Resource;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl implements UserService {

    private UserDao userDao;

    private RoleDao roleDao;

    @Resource
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Resource
    public void setRoleDao(RoleDao roleDao) {
        this.roleDao = roleDao;
    }

    @Override
    public User login(LoginParam param) {
        User user = userDao.getUserByPhone(param.getUserName());
        if (user!=null){
            String passwordHex = Hex.encodeHexString(Digests.md5(param.getPassword().getBytes(), user.getSalt().getBytes()));
            if (StringUtils.equals(user.getPassword(), passwordHex)) {
                return user;
            }
        }
        return null;
    }

    @Override
    public String genToken(User user) throws JOSEException {
        MACSigner macSigner = new MACSigner(JwtConstant.SECRET);
        JWSHeader jwsHeader = new JWSHeader(JWSAlgorithm.HS256);

        List<Role> roles= roleDao.getRolesByUserCode(user.getUserCode());

        List<String> strings =  roles.stream().map(Role::getName).collect(Collectors.toList());
        JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
                .subject(user.getPhone())
                .expirationTime(new Date(System.currentTimeMillis()))
                .claim("userName", user.getUserName())
                .claim("phone", user.getPhone())
                .claim("role",StringUtils.join(strings,","))
                .build();

        SignedJWT signedJWT = new SignedJWT(jwsHeader, claimsSet);
        signedJWT.sign(macSigner);
        return signedJWT.serialize();
    }

    @Override
    public User detail(String subject) {
        return userDao.getUserByCode(subject);
    }

    @Override
    public Page<User> list(PageRequestParam param) {
        PageRequest request=PageRequest.of(param.getPage(), param.getPageSize());
        User query=new User();
        List<User> list =  userDao.getUserList(query,request.getOffset(),request.getPageSize());
        long count = userDao.getUserCount(query);
        return new PageImpl<>(list,request,count);
    }

    @Override
    public User getUserByAccount(String account) {
        return userDao.getUserByPhone(account);
    }

}